package cn.blt.security.config;

import cn.blt.security.auth.entity.LoginUserDetails;
import cn.blt.security.auth.entity.SysUser;
import cn.blt.security.auth.service.SysUserService;
import cn.blt.exception.SaaSException;
import cn.blt.single.UserSingle;
import cn.blt.utils.JwtUtils;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * jwt身份验证令牌filter
 * @author run
 * @date 2022/08/25
 */
@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Resource
    private RedisTemplate<String,String> redisTemplate;

    @Resource
    private SysUserService userService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  {
        try {
            String token = request.getHeader("accessToken");
            if (StringUtils.isEmpty(token)){
                filterChain.doFilter(request, response);
                return;
            }
            String userId = "";
            try{
                LoginUserDetails loginUserDetails = JwtUtils.reqGetUser(request);
                userId = loginUserDetails.getId() +  "";
                if (StringUtils.isEmpty(loginUserDetails.getId())) {
                    throw new SaaSException("用户未登录!");
                }
            }catch(Exception e){
                log.error("reqGetUser => " + e.getMessage());
            }
            String json = redisTemplate.opsForValue().get("login:"+ userId);
            SysUser user = JSONObject.parseObject(json, SysUser.class);
            if (Objects.isNull(user)){
                user = userService.getById(userId);
            }
            UserSingle.setInstance(user);
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user,null,null);
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            filterChain.doFilter(request, response);
        }catch (Exception e) {
            log.error("doFilterInternal error => " + e.getMessage());
        }
    }

}
